/**
 *
 */
package jmine.tec.report.impl;

import java.text.NumberFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import jmine.tec.report.DataRow;
import jmine.tec.report.ExecutableDataColumn;
import jmine.tec.report.ExecutableDataRow;
import jmine.tec.report.cell.DataCell;
import jmine.tec.report.cell.impl.CurrencyDataCell;
import jmine.tec.report.cell.impl.DateDataCell;
import jmine.tec.report.cell.impl.DoubleDataCell;
import jmine.tec.report.cell.impl.PercentageDataCell;
import jmine.tec.report.cell.impl.StringDataCell;

/**
 * Abstract implementation of an {@link ExecutableDataRow}
 * 
 * @author takeshi
 * @version 22/08/2007
 */
public abstract class AbstractExecutableDataRow extends SimpleDataRow implements ExecutableDataRow {

    /**
	 * 
	 */
    private static final long serialVersionUID = 1L;

    /**
     * C'tor
     * 
     * @param name the row name
     */
    public AbstractExecutableDataRow(final String name) {
        super(name);
    }

    /**
     * C'tor
     * 
     * @param nameDataCell the {@link DataCell}
     */
    public AbstractExecutableDataRow(final DataCell nameDataCell) {
        super(nameDataCell);
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value double
     */
    public final void addCurrencyDataCell(final double value) {
        this.addCell(new CurrencyDataCell(value));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value {@link Date}
     */

    public final void addDateDataCell(final Date value) {
        this.addCell(new DateDataCell(value));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value double
     */
    public final void addDoubleDataCell(final double value) {
        this.addCell(new DoubleDataCell(value));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value double
     * @param format o {@link NumberFormat} a ser usado
     */
    public final void addDoubleDataCell(final double value, NumberFormat format) {
        this.addCell(new DoubleDataCell(value, format));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value double
     */
    public final void addPercentageDataCell(final double value) {
        this.addCell(new PercentageDataCell(value));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value double
     * @param format o {@link NumberFormat} a ser usado
     */
    public final void addPercentageDataCell(final double value, NumberFormat format) {
        this.addCell(new PercentageDataCell(value, format));
    }

    /**
     * Adds a data cell to the end of this row's cells.
     * 
     * @param value {@link String}
     */

    public final void addStringDataCell(final String value) {
        this.addCell(new StringDataCell(value));
    }

    /**
     * Gets the executable row on the given index
     * 
     * @param index int
     * @return {@link ExecutableDataRow}
     */
    public final ExecutableDataRow getExecutableDataRow(final int index) {
        return this.getExecutableDataRows().get(index);
    }

    /**
     * @return {@link List}
     */
    public final List<ExecutableDataRow> getExecutableDataRows() {
        final List<ExecutableDataRow> rows = new LinkedList<ExecutableDataRow>();
        for (final DataRow row : this.getChildRows()) {
            if (row instanceof ExecutableDataRow) {
                rows.add(ExecutableDataRow.class.cast(row));
            }
        }
        return rows;
    }

    /**
     * @param index int
     * @return {@link DataCell}
     * @see br.com.maps.fof.report.DataRow#removeCellWithIndex(int)
     */
    @Override
    public final DataCell removeCellWithIndex(final int index) {
        return this.getCells().remove(index);
    }

    /**
     * Executes this row on the given column. By default, it fetches the related object and calls
     * {@link ExecutableDataColumn#executeByObjectType(Class, ExecutableDataRow, Map)} on the type of the object, if its not
     * <code>null</code>. If the related object is null, it calls the same method using the {@link Object} {@link Class} as a literal.
     * Subclasses might want to override this method for proper behaviour.
     * 
     * @param column the column
     * @param params the map with the params
     * @see br.com.maps.util.report.ExecutableDataRow#execute(br.com.maps.util.report.ExecutableDataColumn, java.util.Map)
     */
    public void execute(final ExecutableDataColumn column, final Map<String, Object> params) {
        Object related = this.getRelatedObject();
        Class<?> type = related == null ? Object.class : related.getClass();
        column.executeByObjectType(type, this, params);
    }
}
